package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;

import model.Food;
import model.Snake;

import common.Direction;

import controller.GameEngine;
import controller.KeyController;

public class Snake2GUI {

	private static final int SEGMENT_SIZE = 10;
	private static final int BOARD_SIZE = 400;
	private static final int LETTER_S = 83;
	private static final int LETTER_A = 65;
	private static final int LETTER_W = 87;
	private static final int LETTER_D = 68;
	private static final int DOWN_ARROW = 40;
	private static final int LEFT_ARROW = 39;
	private static final int UP_ARROW = 38;
	private static final int RIGHT_ARROW = 37;
	
	private JFrame frame;
	private GameEngine engine;
	private KeyController keyController;
	private Snake snake1;
	private Snake snake2;
	
	private Thread gameThread;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Snake2GUI window = new Snake2GUI();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}


	/**
	 * Create the application.
	 */
	public Snake2GUI() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		
		frame = new JFrame();
		frame.setBounds(100, 100, 450, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new BorderLayout(0, 0));
		
		JPanel northPanel = new JPanel();
		frame.getContentPane().add(northPanel, BorderLayout.NORTH);
		
		JPanel eastPanel = new JPanel();
		frame.getContentPane().add(eastPanel, BorderLayout.EAST);
		
		JButton startButton = new JButton("Start Game");
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				gameThread.start();
				engine.startGame();
			}
		});
		eastPanel.setLayout(new GridLayout(0, 1, 0, 0));
		
		JButton btnAddPlayer = new JButton("Add Player");
		eastPanel.add(btnAddPlayer);
		eastPanel.add(startButton);
		
		JButton stopGameButton = new JButton("Stop Game");
		stopGameButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				engine.stopGame();
			}
		});
		eastPanel.add(stopGameButton);
		
		JSeparator separator = new JSeparator();
		eastPanel.add(separator);
		
		JLabel lblNumberOfPlayers = new JLabel("Number of Players");
		eastPanel.add(lblNumberOfPlayers);
		
		JLabel label = new JLabel("");
		eastPanel.add(label);
		
		JPanel SouthPanel = new JPanel();
		frame.getContentPane().add(SouthPanel, BorderLayout.SOUTH);
		
		JPanel westPanel = new JPanel();
		frame.getContentPane().add(westPanel, BorderLayout.WEST);
		
		Grass playingArea = new Grass(BOARD_SIZE, SEGMENT_SIZE);
		frame.getContentPane().add(playingArea, BorderLayout.CENTER);
		
		JMenuBar menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);
		
		JMenu gameMenu = new JMenu("Game");
		menuBar.add(gameMenu);
		
		JMenuItem newGameMenuItem = new JMenuItem("New Game");
		gameMenu.add(newGameMenuItem);
		
		JMenuItem exitMenuItem = new JMenuItem("Exit");
		gameMenu.add(exitMenuItem);
		
		engine = new GameEngine(playingArea, BOARD_SIZE, SEGMENT_SIZE);
		
		snake1 = new Snake(Direction.NORTH, Color.CYAN);
		snake2 = new Snake(Direction.SOUTH, Color.ORANGE);
		
		createKeyControllers(snake1, snake2);
		frame.addMouseListener( new MouseAdapter() {

		    public void mouseClicked(MouseEvent e) {
		    	frame.requestFocusInWindow();
		    }

		});
		frame.addKeyListener(keyController);
		frame.setFocusable(true);
		//register at least one player
		engine.addPlayerSnake(snake1);
		engine.addPlayerSnake(snake2);
		
		//add the food
		Food food = new Food(SEGMENT_SIZE, BOARD_SIZE / SEGMENT_SIZE, SEGMENT_SIZE);
		engine.addFood(food);
		//Start the engine
		gameThread = new Thread(engine);
	}
	
	/**
	 * Create the KeyControllers to listen for when the user presses a key 
	 * and to notify a snake it is attached to
	 */
	private void createKeyControllers(Snake snake1, Snake snake2) {
		Map<Direction, Integer> player1Keys = new HashMap<Direction, Integer>();
		player1Keys.put(Direction.WEST, LEFT_ARROW);
		player1Keys.put(Direction.NORTH, UP_ARROW);
		player1Keys.put(Direction.EAST, RIGHT_ARROW);
		player1Keys.put(Direction.SOUTH, DOWN_ARROW);
		
		Map<Direction, Integer> player2Keys = new HashMap<Direction, Integer>();
		player2Keys.put(Direction.WEST, LETTER_D);
		player2Keys.put(Direction.NORTH, LETTER_W);
		player2Keys.put(Direction.EAST, LETTER_A);
		player2Keys.put(Direction.SOUTH, LETTER_S);
		
		keyController = new KeyController();
		keyController.addSnakeKeyMapping(snake1, player1Keys);
		keyController.addSnakeKeyMapping(snake2, player2Keys);
		
	}
}
